package storyteller.ui;

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

import storyteller.FlashWriter;
import storyteller.SmilWriter;

import java.awt.datatransfer.*;
import java.io.*;

public class Main extends JFrame implements ActionListener {


  private static final long serialVersionUID = 3504090534004885511L;
  
  //`````````````````````
  // MEMBER VARIABLES
  //`````````````````````    

  public JMenuBar _menuBar;
  public JMenu _fileMenu, _flashMenu, _smilMenu;
  public JMenuItem _newMenu, _openMenu,_saveMenu,_saveAsMenu,_exitMenu;
  public JMenuItem _createSwfMenu, _createSwfAsMenu, _playSwfMenu;
  public JMenuItem _createSmilMenu, _createSmilAsMenu, _playSmilMenu;
  
  public JMenuItem _copyMenu,_cutMenu,_pasteMenu;
  public JTextArea _typingArea;
  public File _file; // = new File ("file.java");
  public File _swfFile;
  public File _smilFile;
  
  public Dialog _dialog;
  
  
  //`````````````````````
  // CONSTRUCTOR
  //`````````````````````    

  public Main()
  {
    super("");
    init();
  }

  private void init()
  {
    setLookAndFeel();
    setLayout();
    _file = null;
    _swfFile = null;
    _smilFile = null;
    _dialog = new AwtDialog(this);

    createMenuSystem();
    setCurrentFile();
  }


  //`````````````````````
  // INTERFACE
  //`````````````````````   

  public static void main(String[] args){
    new Main().setVisible(true);
  }  
  
  public void actionPerformed(ActionEvent ae)
  {
    JMenuItem source = (JMenuItem)ae.getSource();
    if (source.equals(_openMenu)) doOpen();
    else if (source.equals(_newMenu)) doNew();
    else if (source.equals(_saveMenu)) doSave(false);
    else if (source.equals(_saveAsMenu)) doSave(true);
    else if (source.equals(_exitMenu)) doExit();
    else if (source.equals(_createSmilMenu)) doSmil(false);
    else if (source.equals(_createSmilAsMenu)) doSmil(true);
    else if (source.equals(_createSwfMenu)) doFlash(false);
    else if (source.equals(_playSwfMenu)) doPlayFlash();
    else if (source.equals(_playSmilMenu)) doPlaySmil();
    else if (source.equals(_createSwfAsMenu)) doFlash(true);
    else if (source.equals(_copyMenu)) copy();
    else if (source.equals(_cutMenu)) cut();
    else if (source.equals(_pasteMenu)) paste();
    
    updateMenus();
  }
  
  public void doOpen() 
  {
    File potentialFile = _dialog.openDialog();
    if (potentialFile == null)
    {
      return;
    }
    _file = potentialFile;
    setCurrentFile();
    String fileContent = readFileContents(_file);
    _typingArea.setText(fileContent);
  }
  

  public void doSave(boolean shouldSelectNewFile) 
  {
    boolean mustSelectNewFile = _file == null;
    
    if (mustSelectNewFile || shouldSelectNewFile)
    {
      File potentialFile = _dialog.saveDialog();
      if (potentialFile == null)
      {
        return;
      }
      _file = potentialFile;
    }
    
    writeFileContents(_file, _typingArea.getText());
    setCurrentFile();
  }
  
  public void doSmil(boolean shouldSelectNewFile)
  {
    boolean mustSelectNewFile = _smilFile == null;
    
    if (mustSelectNewFile || shouldSelectNewFile)
    {
      File potentialFile = _dialog.saveDialog();
      if (potentialFile == null)
      {
        return;
      }
      _smilFile = potentialFile;
    }
    SmilWriter writer = new SmilWriter(_smilFile.getAbsolutePath());
    writer.parseContent(_typingArea.getText());
    writer.save();
    _dialog.messageDialog("Finished Creating ["+ _smilFile.getName() +"]");
  }
  
  public void doFlash(boolean shouldSelectNewFile)
  {
    boolean mustSelectNewFile = _swfFile == null;
    
    if (mustSelectNewFile || shouldSelectNewFile)
    {
      File potentialFile = _dialog.saveDialog();
      if (potentialFile == null)
      {
        return;
      }
      _swfFile = potentialFile;
    }
    
    FlashWriter writer = new FlashWriter(_swfFile.getAbsolutePath());
    writer.parseContent(_typingArea.getText());
    writer.save();
    _dialog.messageDialog("Finished Creating ["+ _swfFile.getName() +"]");
  }
  
  public void doPlayFlash()
  {
    boolean didSucceed = FlashBrowser.launch(_swfFile.getAbsolutePath());
    if (!didSucceed)
    {
      _dialog.messageDialog("Unable to play flash file: [" + _swfFile.getAbsolutePath()  + "]");
    }
  }
  
  public void doPlaySmil()
  {
    boolean didSucceed = SmilBrowser.launch(_smilFile.getAbsolutePath());
    if (!didSucceed)
    {
      _dialog.messageDialog("Unable to play smil file: [" + _smilFile.getAbsolutePath()  + "]");
    }
  }  

  public void copy() {
    String s = _typingArea.getSelectedText();
    _typingArea.getSelectionStart();
    _typingArea.getSelectionEnd();
    StringSelection ss = new
    StringSelection(s);
    // Set the content to the clipboard.
    this.getToolkit().getSystemClipboard().
    setContents(ss, ss);
  }
  public void cut() {
    String s = _typingArea.getSelectedText();
    int start=_typingArea.getSelectionStart();
    int end=_typingArea.getSelectionEnd();
    _typingArea.replaceRange("",start,end);
    StringSelection ss = new
    StringSelection(s);
    // Set the content to the clipboard.
    this.getToolkit().getSystemClipboard().setContents(ss,
        ss);
  }
  public void paste() {
    Clipboard cb =
      this.getToolkit().getSystemClipboard();
    Transferable tr = cb.getContents(this);
    try {
      // Get the content from the clipboard.
      String s = (String)
      tr.getTransferData(DataFlavor.stringFlavor);
      int start=_typingArea.getSelectionStart();
      int end=_typingArea.getSelectionEnd();
      _typingArea.replaceRange(s,start,end);
    }
    catch (Exception e) {
      return;
    }
  }

  
  
  public void doExit() {
    System.exit(0);
  }



  //`````````````````````
  // PRIVATE METHODS
  //`````````````````````    

  private void doNew()
  {
    _file = null;
    _swfFile = null;
    _smilFile = null;
    setCurrentFile();
    _typingArea.setText("");
  }  
  
  private void setLookAndFeel()
  {
    try 
    {
      UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
    }
    catch (Exception e) 
    {
      throw new RuntimeException("Unable to look specific look and feel",e);
    }    
  }

  private void setLayout()
  {
    Container contentpane = getContentPane();
    contentpane.setLayout (new BorderLayout());
    setSize(300, 300);
    _typingArea = new JTextArea();
    _typingArea.setDragEnabled(true);
    contentpane.add ( _typingArea, "Center");

  }

  private void createMenuSystem()
  {
    this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

    _menuBar = new JMenuBar();
    setJMenuBar(_menuBar);


    _fileMenu = addMenu(_menuBar, "File", KeyEvent.VK_F);
    _newMenu = addMenuItem(_fileMenu, "New", KeyEvent.VK_N);
    _openMenu = addMenuItem(_fileMenu, "Open", KeyEvent.VK_O);
    _saveMenu = addMenuItem(_fileMenu, "Save", KeyEvent.VK_S);
    _saveAsMenu = addMenuItem(_fileMenu, "Save As...", KeyEvent.VK_A);
    _fileMenu.addSeparator();
    _copyMenu = addMenuItem(_fileMenu, "Copy", KeyEvent.VK_C);
    _cutMenu = addMenuItem(_fileMenu, "Cut", KeyEvent.VK_X);
    _pasteMenu = addMenuItem(_fileMenu, "Paste", KeyEvent.VK_P);
    _fileMenu.addSeparator();
    _exitMenu = addMenuItem(_fileMenu, "Exit", -1);
    
    _flashMenu = addMenu(_menuBar, "Flash", KeyEvent.VK_L);
    _createSwfMenu = addMenuItem(_flashMenu, "Create blah.swf", KeyEvent.VK_S);
    _createSwfAsMenu = addMenuItem(_flashMenu, "Create As...", KeyEvent.VK_A);
    _playSwfMenu = addMenuItem(_flashMenu, "Play", KeyEvent.VK_P);
    
    _smilMenu = addMenu(_menuBar, "Smil", KeyEvent.VK_S);
    _createSmilMenu = addMenuItem(_smilMenu, "Create blah.smil", KeyEvent.VK_S);
    _createSmilAsMenu = addMenuItem(_smilMenu, "Create As...", KeyEvent.VK_A);
    _playSmilMenu = addMenuItem(_smilMenu, "Play", KeyEvent.VK_P);    
    
    updateMenus();
  }
  
  public static boolean writeFileContents(File file, String content) 
  {
    try 
    {
      PrintWriter pw = new PrintWriter (new BufferedWriter (new FileWriter (file)));
      pw.print(content);
      pw.flush();
      pw.close();
    }
    catch (IOException e) 
    {
      return false;
    }
    return true;
  }
  

  private String readFileContents(File file) 
  {
    StringBuffer strBuffer;
    String fileContent=null;
    String lineString;
    try {
      FileReader fr = new FileReader(file);
      BufferedReader br = new
      BufferedReader(fr);
      strBuffer = new StringBuffer() ;
      while ((lineString = br.readLine()) != null) {
        strBuffer.append (lineString + "\n");
      }
      fr.close();
      fileContent = strBuffer.toString();
    }
    catch (IOException e ) {
      return null;
    }
    return fileContent;
  }
  
  private void setCurrentFile()
  {
    if (_file == null)
    {
      setTitle("Grad - Tell your story, better");
    }
    else
    {
      setTitle("Grad - " + _file.getAbsolutePath());
      _swfFile = new File(_file.getParent(),renameFilename(_file.getName(),".swf"));
      _smilFile = new File(_file.getParent(),renameFilename(_file.getName(),".smil"));
      
      
    }
  }  
  
  private String renameFilename(String nameWithExtension, String newExtension)
  {
    int dotIndex = nameWithExtension.indexOf(".");
    if (dotIndex == -1)
    {
      return nameWithExtension + newExtension;
    }
    else
    {
      return nameWithExtension.substring(0, dotIndex) + newExtension;
    }
  }
  
  private void updateMenus()
  {
    if (_file == null)
    {
      _saveMenu.setText("Save");
    }
    else
    {
      String filename = _file.getName();
      _saveMenu.setText("Save " + filename);
    }

    if (_swfFile == null)
    {
      _createSwfMenu.setText("Create");
      _createSwfMenu.setEnabled(false);
    }
    else
    {
      String filename = _swfFile.getName();
      _createSwfMenu.setText("Create " + filename);
      _createSwfMenu.setEnabled(true);
    }

    if (_smilFile == null)
    {
      _createSmilMenu.setText("Create");
      _createSmilMenu.setEnabled(false);
    }
    else
    {
      String filename = _smilFile.getName();
      _createSmilMenu.setText("Create " + filename);
      _createSmilMenu.setEnabled(true);
    }

    configureFile(_swfFile,_playSwfMenu);
    configureFile(_smilFile,_playSmilMenu);
  }

  private void configureFile(File file, JMenuItem menu)
  {
    if (file == null || !file.exists())
    {
      menu.setText("Play");
      menu.setEnabled(false);
    }
    else
    {
      String filename = file.getName();
      menu.setText("Play " + filename);
      menu.setEnabled(true);
    }    
  }
  
  private JMenu addMenu(JMenuBar parent, String text, int shortCut)
  {
    JMenu child = new JMenu(text);
    child.setMnemonic(shortCut);
    parent.add(child);
    child.addActionListener(this);
    return child;
  }  
  
  private JMenuItem addMenuItem(JMenu parent, String text, int shortCut)
  {
    JMenuItem child = new JMenuItem(text);
    if (shortCut != -1)
    {
      child.setMnemonic(shortCut);  
    }
    parent.add(child);
    child.addActionListener(this);
    return child;
  }

}